package com.example.frame;

import com.example.config.GameConfig;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Arrays;

// 创建一个俄罗斯方块类
class Tetrisblok extends JPanel implements KeyListener {

    // blockType 代表方块类型
    // turnState代表方块状态


    private int blockType;
    private int score = 0;

    private int turnState;

    private int x;

    private int y;

    private int i = 0;

    private int j = 0;

    int flag = 0;
    // 定义已经放下的方块x=0-11,y=0-21;
    int[][] map = new int[13][23];

    int blockCount = 0;
    int curRandomNum = GameConfig.getSeed();
    

    // 生成新方块的方法
    public void newblock() {

        //改为固定数值
        int shapeIndex = 0;
        curRandomNum = GameConfig.getRandomNumber(curRandomNum);
        // I,L,J,T,O,S,Z 型方块的概率权重分别为：2,3,3,4,5,6,6（和为29）
        int weightIndex = curRandomNum % 29;
        if (weightIndex >= 0 && weightIndex <= 1) {
            shapeIndex = 0;
        } else if (weightIndex > 1 && weightIndex <= 4) {
            shapeIndex = 1;
        } else if (weightIndex > 4 && weightIndex <= 7) {
            shapeIndex = 2;
        } else if (weightIndex > 7 && weightIndex <= 11) {
            shapeIndex = 3;
        } else if (weightIndex > 11 && weightIndex <= 16) {
            shapeIndex = 4;
        } else if (weightIndex > 16 && weightIndex <= 22) {
            shapeIndex = 5;
        } else if (weightIndex > 22) {
            shapeIndex = 6;
        }

//        blockType = (int) (Math.random() * 1000) % 7;
//        turnState = (int) (Math.random() * 1000) % 4;


        blockType = shapeIndex;
        turnState = (blockCount)%4;
        blockCount++;

        System.out.println("blockCount="+blockCount+",shapeIndex="+shapeIndex+",turnState="+turnState+",curRandomNum="+curRandomNum);
        x = 2;
        y = 1;
        if (gameover(x, y) == 1) {
            showMap();
            initGameState();
            JOptionPane.showMessageDialog(null, "GAME OVER");
        }
    }

    private void initGameState() {
        score = 0;
        blockCount=0;
        curRandomNum = GameConfig.getSeed();
        newmap();
        drawwall();
        newblock();
    }

    // 画围墙
    public void drawwall() {
        for (i = 0; i < 12; i++) {
            map[i][21] = 2;
        }
        for (j = 0; j < 22; j++) {
            map[11][j] = 2;
            map[0][j] = 2;
        }
    }

    // 初始化地图
    public void newmap() {
        for (i = 0; i < 12; i++) {
            for (j = 0; j < 22; j++) {
                map[i][j] = 0;
            }
        }
    }

    // 初始化构造方法
    Tetrisblok() {
        initGameState();
//        Timer timer = new Timer(1000, new TimerListener());
//        timer.start();
    }

    // 旋转的方法
    public void turn() {
        int tempturnState = turnState;
        turnState = (turnState + 1) % 4;
//        if (blow(x, y, blockType, turnState) == 1) {
//        }

        if (blow(x, y, blockType, turnState) == 0) {
            turnState = tempturnState;
        }
        repaint();
    }

    // 左移的方法
    public void left() {
        if (blow(x - 1, y, blockType, turnState) == 1) {
            x = x - 1;
        }
        repaint();
    }

    // 右移的方法
    public void right() {
        if (blow(x + 1, y, blockType, turnState) == 1) {
            x = x + 1;
        }
        ;
        repaint();
    }

    // 下落的方法
    public void down() {
        if (blow(x, y + 1, blockType, turnState) == 1) {
            y = y + 1;
            delline();
        }else{
            if (blow(x, y + 1, blockType, turnState) == 0) {
                add(x, y, blockType, turnState);
                newblock();
                delline();
            }
        }

        repaint();
    }
    // 下落的方法
    public void down(int distance) {
        if (blow(x, y + distance, blockType, turnState) == 1) {
            y = y + distance;
            delline();
        }else{
            if (blow(x, y + 1, blockType, turnState) == 0) {
                add(x, y, blockType, turnState);
                newblock();
                delline();
            }
        }

        repaint();
    }
    // 快速下落的方法
    public void quickDown() {
        int maxDownDistance = getMaxDownDistance();
        down(maxDownDistance);
//        while(true){
//            if (blow(x, y + 1, blockType, turnState) == 1) {
//                y = y + 1;
//                delline();
//            }
//            if (blow(x, y + 1, blockType, turnState) == 0) {
//                add(x, y, blockType, turnState);
//                newblock();
//                delline();
//                break;
//            }
//        }
        repaint();
    }
    public int getMaxDownDistance(){
        int res = 1;
        while(true){
            if(blow(x , y+res, blockType, turnState) != 1){
                res--;
                break;
            }
            res++;
        }
        return res;
    }
    // 是否合法的方法
    public int blow(int x, int y, int blockType, int turnState) {
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                if (((GameConfig.shapes[blockType][turnState][a * 5 + b] == 1) && (map[x
                        + b + 1][y + a] == 1))
                        || ((GameConfig.shapes[blockType][turnState][a * 5 + b] == 1) && (map[x
                        + b + 1][y + a] == 2))) {

                    return 0;
                }
            }
        }
        return 1;
    }

    // 消行的方法
    public void delline() {
        int c = 0;
        int sum = 0;
        int n = 0;//1234对应(1 3 6 10)
        int x = 0;
        for (int b = 0; b < 22; b++) {
            for (int a = 0; a < 12; a++) {
                if (map[a][b] == 1) {
                    sum++;
                    c = c + 1;
                    if (c == 10) {
//                        score += 10;
                        n++;
                        for (int d = b; d > 0; d--) {
                            for (int e = 0; e < 11; e++) {
                                map[e][d] = map[e][d - 1];

                            }
                        }
                    }
                }
            }

            c = 0;
        }
        if(n>=1){
            switch (n){
                case 1:x = 1;break;
                case 2:x = 3;break;
                case 3:x = 6;break;
                case 4:x = 10;break;
                default:break;
            }
            score += sum * x;
        }

    }

    // 判断你挂的方法
    public int gameover(int x, int y) {
        if (blow(x, y, blockType, turnState) == 0) {
            return 1;
        }
        return 0;
    }

    // 把当前添加map
    public void add(int x, int y, int blockType, int turnState) {
        int j = 0;
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                if (map[x + b + 1][y + a] == 0) {
                    map[x + b + 1][y + a] = GameConfig.shapes[blockType][turnState][j];
                }
                j++;
            }
        }
    }

    // 画方块的的方法
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // 画当前方块
        for (j = 0; j < 25; j++) {
            if (GameConfig.shapes[blockType][turnState][j] == 1) {
                g.fillRect((j % 5 + x + 1) * 10, (j / 5 + y) * 10, 10, 10);
            }
        }
        // 画已经固定的方块
        for (j = 0; j < 22; j++) {
            for (i = 0; i < 12; i++) {
                if (map[i][j] == 1) {
                    g.fillRect(i * 10, j * 10, 10, 10);

                }
                if (map[i][j] == 2) {
                    g.drawRect(i * 10, j * 10, 10, 10);

                }
            }
        }
        g.drawString("score=" + score, 125, 10);
    }

    // 键盘监听
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_DOWN:
                down();
                break;
            case KeyEvent.VK_UP:
                turn();
                break;
            case KeyEvent.VK_RIGHT:
                right();
                break;
            case KeyEvent.VK_LEFT:
                left();
                break;
            case KeyEvent.VK_SPACE:
                //快速下落
                quickDown();
                break;
            default:
                break;
        }

    }

    // 无用
    public void keyReleased(KeyEvent e) {
    }

    // 无用
    public void keyTyped(KeyEvent e) {
    }

    // 定时器监听
    class TimerListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {

            repaint();
            if (blow(x, y + 1, blockType, turnState) == 1) {
                y = y + 1;
                delline();
            }
            ;
            if (blow(x, y + 1, blockType, turnState) == 0) {

                if (flag == 1) {
                    add(x, y, blockType, turnState);
                    delline();
                    newblock();
                    flag = 0;
                }
                flag = 1;
            }
            ;
        }
    }
    public void showMap(){
        System.out.println(this.toString());
    }
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        for(int k=0;k<map[0].length;k++){
            for(int l=0;l<map.length;l++){
                if(map[l][k] == 2){
                    sb.append("*\t");
                }
                if(map[l][k] == 0){
                    sb.append(" \t");
                }
                if(map[l][k] == 1){
                    sb.append("#\t");
                }
            }
            sb.append("\n");
        }
        sb.append(blockCount);
        return sb.toString();
    }
}
